﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using Microsoft.SharePoint.Administration;
using System.Collections.ObjectModel;
using Microsoft.SharePoint;

namespace SPVisualDev.Services
{
    public class Worker : MarshalByRefObject
    {
        private string m_last_resolve_req;

        public string LastErrorMsg
        {
            get;
            private set;
        }

        public Worker()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }

        private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            if (args.Name == m_last_resolve_req)
                return null;// throw new Exception("Assembly could not be found.");

            m_last_resolve_req = args.Name;

            return Assembly.Load(args.Name);

        }

        public string GetAssemblyFullName(string AssemblyFilePath)
        {
            try
            {
                string fullName = Assembly.LoadFile(AssemblyFilePath).FullName;

                return fullName;
            }
            catch (Exception ex)
            {
                this.LastErrorMsg = ex.Message;
                return null;
            }
        }

        public string GetGacPathForAssembly(string FullName)
        {
            try
            {
                string path = Path.GetDirectoryName(Assembly.Load(FullName).CodeBase);

                return path;
            }
            catch (Exception ex)
            {
                this.LastErrorMsg = ex.Message;
                return null;
            }
        }

        public bool InstallFeature(string FeatureName, bool Force)
        {
            try
            {
                Features.InstallFeature(FeatureName, Force);

                return true;
            }
            catch (Exception ex)
            {
                this.LastErrorMsg = ex.Message;
                return false;
            }
        }

        public bool UninstallFeature(string FeatureName, bool Force)
        {
            try
            {
                Features.UninstallFeature(FeatureName, Force);

                return true;
            }
            catch (Exception ex)
            {
                this.LastErrorMsg = ex.Message;
                return false;
            }
        }

        public bool ActivateFeature(string FeatureName, string Url, bool Force)
        {
            try
            {
                Features.ActivateFeature(FeatureName, Url, Force);

                return true;
            }
            catch (Exception ex)
            {
                this.LastErrorMsg = ex.Message;
                return false;
            }
        }

        public bool DeactivateFeature(string FeatureName, string Url, bool Force)
        {
            try
            {
                Features.DeactivateFeature(FeatureName, Url, Force);

                return true;
            }
            catch (Exception ex)
            {
                this.LastErrorMsg = ex.Message;
                return false;
            }
        }

        public bool DeployWSP(string WSPFilePath, string[] WebApplicationURLs, bool bGAC)
        {
            try
            {
                SPSolution sol = SPFarm.Local.Solutions[Path.GetFileName(WSPFilePath)];
                if (sol != null)
                {
                    if (sol.Deployed)
                    {
                        if (sol.DeployedWebApplications != null && sol.DeployedWebApplications.Count > 0)
                            sol.RetractLocal(sol.DeployedWebApplications);
                        else
                            sol.RetractLocal();
                    }

                    while (sol.DeploymentState != SPSolutionDeploymentState.NotDeployed)
                    {
                        System.Threading.Thread.Sleep(1000);
                    }

                    sol.Delete();
                }


                sol = SPFarm.Local.Solutions.Add(WSPFilePath);

                if (WebApplicationURLs.Length > 0)
                {
                    Collection<SPWebApplication> web_app_coll = new Collection<SPWebApplication>();

                    foreach (string url in WebApplicationURLs)
                    {
                        web_app_coll.Add(SPWebApplication.Lookup(new Uri(url)));
                    }

                    sol.DeployLocal(bGAC, web_app_coll, true);
                }
                else
                {
                    try
                    {
                        sol.DeployLocal(bGAC, true);
                    }
                    catch (SPException ex)
                    {
                        if (ex.ErrorCode != -2146232832)
                            throw;

                        Collection<SPWebApplication> web_app_coll = new Collection<SPWebApplication>();
                        foreach (SPWebApplication webapp in SPWebService.ContentService.WebApplications)
                            web_app_coll.Add(webapp);

                        foreach (SPWebApplication webapp in SPWebService.AdministrationService.WebApplications)
                            web_app_coll.Add(webapp);

                        sol.DeployLocal(bGAC, web_app_coll, true);
                    }
                }

                IIS.RecycleIISAppPool(null);

                return true;
            }
            catch (Exception ex)
            {
                this.LastErrorMsg = ex.Message;
                return false;
            }
        }

//        AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
    }
}
